﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Ruanmou.Framework.CacheExtend
{
    /// <summary>
    /// 自定义缓存
    /// </summary>
    public class CustomCache
    {

        /// <summary>
        /// private 保护数据  不北篡改
        /// static  全局唯一  不释放
        /// 
        /// </summary>
        private static Dictionary<string, KeyValuePair<object,DateTime>>  _CustomCacheDictionary;



        //如果要线程安全，对一块内存的操作， 必须是单线程的;


        /// <summary>
        /// 线程安全的字典
        /// </summary>
        //private static System.Collections.Concurrent.ConcurrentDictionary

        static CustomCache()
        {
            _CustomCacheDictionary = new Dictionary<string, KeyValuePair<object, DateTime>>();
            Console.WriteLine($"{DateTime.Now.ToString("MM-dd HH:mm:ss fff")} 初始化缓存");


            Task.Run(() =>
            {
                while (true)
                {
                    LockAction(new Action(() =>
                    {
                        List<string> ls = new List<string>();
                        foreach (var key in _CustomCacheDictionary.Keys)
                        {
                            var valueTime = _CustomCacheDictionary[key];
                            if (valueTime.Value > DateTime.Now)
                            {

                            }
                            else
                            {
                                ls.Add(key);
                            }
                        }

                        ls.ForEach(key => _CustomCacheDictionary.Remove(key));
                    }));
                    Thread.Sleep(1000 * 60 * 10);
                }
            });

            //这一句话 可以追溯到系统什么时候重启， 日志
        }


        /// <summary>
        /// 保存数据
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void Add(string key, object value,int seconde =1800)
        {
            LockAction(new Action(() =>
            {
                _CustomCacheDictionary.Add(key, new KeyValuePair<object, DateTime>(value, DateTime.Now.AddSeconds(seconde)));
            }));
        }



        private static readonly object CustomCache_Lock = new object();

        private static void LockAction(Action action)
        {
            lock (CustomCache_Lock)
            {
                action.Invoke();
            }
        }


        /// <summary>
        /// 保存数据，有就覆盖  没有就新增
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void SaveOrUpdate(string key, object value, int seconde = 1800)
        {
            LockAction(new Action(() =>
            {
                _CustomCacheDictionary[key] = new KeyValuePair<object, DateTime>(value, DateTime.Now.AddSeconds(seconde));
            }));
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T Get<T>(string key)
        {
            return (T)_CustomCacheDictionary[key].Key;
        }


        /// <summary>
        /// 检查是否存在key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool Exsit(string key)
        {
            if (_CustomCacheDictionary.ContainsKey(key))
            {
                var valueTime = _CustomCacheDictionary[key];
                if (valueTime.Value > DateTime.Now)
                {
                    return true;
                }
                else
                {
                    _CustomCacheDictionary.Remove(key);
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 进阶缓存的使用
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public T Find<T>(string key, Func<T> func, int seconde = 1800)
        {
            T s = default(T);
            if (!Exsit(key))
            {
                s = func.Invoke();
                _CustomCacheDictionary.Add(key, new KeyValuePair<object, DateTime>(s, DateTime.Now.AddSeconds(seconde)));
            }
            else
            {
                s = Get<T>(key);
            }
            return s;
        }

        /// <summary>
        /// 删除指定缓存
        /// </summary>
        /// <param name="key"></param>
        public static void Remove(string key)
        {
            _CustomCacheDictionary.Remove(key);
        }


        /// <summary>
        /// 清空缓存
        /// </summary>
        public static void RemoveAll()
        {
            _CustomCacheDictionary.Clear();
        }



        /// <summary>
        /// 移除指定的缓存
        /// </summary>
        /// <param name="func"></param>
        public static void RemoveCondition(Func<string,bool> func)
        {
            List<string> ls = new List<string>();
            foreach (var item in _CustomCacheDictionary.Keys)
            {
                if (func.Invoke(item))
                {
                    ls.Add(item);
                   
                }
            }
            ls.ForEach((x) => _CustomCacheDictionary.Remove(x));
        }
    }
}
